package com.talkweb.citypickerview.style.cityjd;


import com.talkweb.citypickerview.Interface.OnCityItemClickListener;
import com.talkweb.citypickerview.ResourceTable;
import com.talkweb.citypickerview.bean.CityBean;
import com.talkweb.citypickerview.bean.DistrictBean;
import com.talkweb.citypickerview.bean.ProvinceBean;
import com.talkweb.citypickerview.citywheel.CityParseHelper;
import com.talkweb.citypickerview.style.citylist.Toast.ToastUtils;
import com.talkweb.citypickerview.utils.utils;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.PopupDialog;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.global.icu.text.Normalizer2;

import java.util.List;

/**
 * 仿京东城市选择器
 * 作者：liji on 2018/1/26 16:08
 * 邮箱：lijiwork@sina.com
 * QQ ：275137657
 */

public class JDCityPicker {

    private ListContainer mCityListView;

    private Text mProTv;

    private Text mCityTv;

    private Text mAreaTv;
    private Image mCloseImg;

    private PopupDialog popwindow;
    private Component mSelectedLine;
    private Component popview;

    private CityParseHelper parseHelper;
    private ProvinceAdapter mProvinceAdapter;
    private CityAdapter mCityAdapter;
    private AreaAdapter mAreaAdapter;

    private List<ProvinceBean> provinceList = null;
    private List<CityBean> cityList = null;
    private List<DistrictBean> areaList = null;

    private int tabIndex = JDConst.INDEX_TAB_PROVINCE;
    private Context context;
    private String colorSelected = "#ff181c20";
    private String colorAlert = "#ffff4444";

    private OnCityItemClickListener mBaseListener;

    private JDCityConfig cityConfig = null;

    public void setOnCityItemClickListener(OnCityItemClickListener listener) {
        mBaseListener = listener;
    }

    public void setConfig(JDCityConfig cityConfig) {
        this.cityConfig = cityConfig;
    }


    private void initJDCityPickerPop() {

        if (this.cityConfig == null) {
            this.cityConfig = new JDCityConfig.Builder().setJDCityShowType(JDCityConfig.ShowType.PRO_CITY_DIS).build();
        }

        tabIndex = JDConst.INDEX_TAB_PROVINCE;
        //解析初始数据
        if (parseHelper == null) {
            parseHelper = new CityParseHelper();
        }

        if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
            ToastUtils.showLongToast(context, "请调用init方法进行初始化相关操作");
            return;
        }


        LayoutScatter layoutInflater = LayoutScatter.getInstance(context);
        popview = layoutInflater.parse(ResourceTable.Layout_pop_jdcitypicker, null, false);

        mCityListView = (ListContainer) popview.findComponentById(ResourceTable.Id_city_listview);
        mProTv = (Text) popview.findComponentById(ResourceTable.Id_province_tv);
        mCityTv = (Text) popview.findComponentById(ResourceTable.Id_city_tv);
        mAreaTv = (Text) popview.findComponentById(ResourceTable.Id_area_tv);
        mCloseImg = (Image) popview.findComponentById(ResourceTable.Id_close_img);
        mSelectedLine = popview.findComponentById(ResourceTable.Id_selected_line);


        popwindow = new PopupDialog(context, popview, ComponentContainer.LayoutConfig.MATCH_PARENT,
                ComponentContainer.LayoutConfig.MATCH_CONTENT);
        popwindow.setCustomComponent(popview);
      popwindow.setBackColor(Color.WHITE);
        popwindow.setAutoClosable(true);

        mCloseImg.setClickedListener(v -> {
            hidePop();
            utils.setBackgroundAlpha(context, 1.0f);
            if (mBaseListener != null) {
                mBaseListener.onCancel();
            }
        });

        mProTv.setClickedListener(v -> {
            tabIndex = JDConst.INDEX_TAB_PROVINCE;
            if (mProvinceAdapter != null) {
                mCityListView.setItemProvider(mProvinceAdapter);
                if (mProvinceAdapter.getSelectedPosition() != JDConst.INDEX_INVALID) {
                    //mCityListView.setSelection(mProvinceAdapter.getSelectedPosition());
                }
            }
            updateTabVisible();
            updateIndicator();
        });
        mCityTv.setClickedListener(v -> {
            tabIndex = JDConst.INDEX_TAB_CITY;
            if (mCityAdapter != null) {
                mCityListView.setItemProvider(mCityAdapter);
                if (mCityAdapter.getSelectedPosition() != JDConst.INDEX_INVALID) {
                    //mCityListView.setSelection(mCityAdapter.getSelectedPosition());
                }
            }
            updateTabVisible();
            updateIndicator();
        });
        mAreaTv.setClickedListener(v -> {
            tabIndex = JDConst.INDEX_TAB_AREA;
            if (mAreaAdapter != null) {
                mCityListView.setItemProvider(mAreaAdapter);
                if (mAreaAdapter.getSelectedPosition() != JDConst.INDEX_INVALID) {
                    //mCityListView.setSelection(mAreaAdapter.getSelectedPosition());
                }
            }
            updateTabVisible();
            updateIndicator();
        });
        mCityListView.setItemClickedListener((listContainer, component, position, id) -> selectedList(position));

        utils.setBackgroundAlpha(context, 0.5f);
        updateIndicator();
        updateTabsStyle(JDConst.INDEX_INVALID);
        setProvinceListData();

    }

    private void selectedList(int position) {
        switch (tabIndex) {
            case JDConst.INDEX_TAB_PROVINCE:
                ProvinceBean provinceBean = mProvinceAdapter.getItem(position);
                if (provinceBean != null) {
                    mProTv.setText("" + provinceBean.getName());
                    mCityTv.setText("请选择");
                    mProvinceAdapter.updateSelectedPosition(position);
                    mProvinceAdapter.notifyDataChanged();
                    mCityAdapter = new CityAdapter(context, provinceBean.getCityList());
                    //选中省份数据后更新市数据
                    InnerEvent innerEvent = InnerEvent.get(JDConst.INDEX_TAB_CITY, provinceBean.getCityList());
                    mHandler.sendEvent(innerEvent);
                }

                break;


            case JDConst.INDEX_TAB_CITY:
                CityBean cityBean = mCityAdapter.getItem(position);
                if (cityBean != null) {
                    mCityTv.setText("" + cityBean.getName());
                    mAreaTv.setText("请选择");
                    mCityAdapter.updateSelectedPosition(position);
                    mCityAdapter.notifyDataChanged();
                    if (this.cityConfig != null && this.cityConfig.getShowType() == JDCityConfig.ShowType.PRO_CITY) {
                        callback(new DistrictBean());
                    } else {
                        mAreaAdapter = new AreaAdapter(context, cityBean.getCityList());
                        //选中省份数据后更新市数据
                        InnerEvent innerEvent = InnerEvent.get(JDConst.INDEX_TAB_AREA, cityBean.getCityList());
                        mHandler.sendEvent(innerEvent);
                    }
                }
                break;

            case JDConst.INDEX_TAB_AREA:
                //返回选中的省市区数据
                DistrictBean districtBean = mAreaAdapter.getItem(position);
                if (districtBean != null) {
                    callback(districtBean);
                }
                break;
            default:
        }
    }

    /**
     * 设置默认的省份数据
     */
    private void setProvinceListData() {
        provinceList = parseHelper.getProvinceBeanArrayList();
        if (provinceList != null && !provinceList.isEmpty()) {
            mProvinceAdapter = new ProvinceAdapter(context, provinceList);
            mCityListView.setItemProvider(mProvinceAdapter);
        } else {
            ToastUtils.showLongToast(context, "解析本地城市数据失败！");
            return;
        }

    }

    /**
     * 初始化，默认解析城市数据，提交加载速度
     */
    public void init(Context context) {
        this.context = context;
        parseHelper = new CityParseHelper();

        //解析初始数据
        if (parseHelper.getProvinceBeanArrayList().isEmpty()) {
            parseHelper.initData(context);
        }

    }


    /**
     * 更新选中城市下面的红色横线指示器
     */
    private void updateIndicator() {
        popview.getContext().getUITaskDispatcher().asyncDispatch(() -> {
            switch (tabIndex) {
                case JDConst.INDEX_TAB_PROVINCE:
                    tabSelectedIndicatorAnimation(mProTv).start();
                    break;
                case JDConst.INDEX_TAB_CITY:
                    tabSelectedIndicatorAnimation(mCityTv).start();
                    break;
                case JDConst.INDEX_TAB_AREA:
                    tabSelectedIndicatorAnimation(mAreaTv).start();
                    break;
                default:
            }
        });

    }

    /**
     * tab 选中的红色下划线动画
     *
     * @param tab
     * @return
     */
    private AnimatorGroup tabSelectedIndicatorAnimation(Text tab) {
        AnimatorProperty xAnimator = mSelectedLine.createAnimatorProperty()
                .moveFromX(mSelectedLine.getPivotX())
                .moveToX(tab.getPivotX());

        final ComponentContainer.LayoutConfig params = mSelectedLine.getLayoutConfig();
        AnimatorValue widthAnimator = new AnimatorValue();
        widthAnimator.setValueUpdateListener((animatorValue, v) -> {
            params.width = (int) (v * params.width / tab.getWidth());
            mSelectedLine.setLayoutConfig(params);
        });

        AnimatorGroup set = new AnimatorGroup();
        set.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
        set.runParallel(xAnimator, widthAnimator);

        return set;
    }

    public void showCityPicker() {
        initJDCityPickerPop();
        if (!isShow()) {
            popwindow.showOnCertainPosition(TextAlignment.BOTTOM, 0, 0);
        }
    }


    private void hidePop() {
        if (isShow()) {
            popwindow.hide();
        }
    }

    private boolean isShow() {
        return popwindow.isShowing();
    }


    private void updateTabVisible() {
        mProTv.setVisibility(provinceList == null || provinceList.isEmpty() ? Component.HIDE : Component.VISIBLE);
        mCityTv.setVisibility(cityList == null || cityList.isEmpty() ? Component.HIDE : Component.VISIBLE);
        mAreaTv.setVisibility(areaList == null || areaList.isEmpty() ? Component.HIDE : Component.VISIBLE);
    }


    /**
     * 选择回调
     *
     * @param districtBean
     */
    private void callback(DistrictBean districtBean) {

        ProvinceBean provinceBean = provinceList != null &&
                !provinceList.isEmpty() &&
                mProvinceAdapter != null &&
                mProvinceAdapter.getSelectedPosition() != JDConst.INDEX_INVALID ?
                provinceList.get(mProvinceAdapter.getSelectedPosition()) : null;

        CityBean cityBean = cityList != null &&
                !cityList.isEmpty() &&
                mCityAdapter != null &&
                mCityAdapter.getSelectedPosition() != JDConst.INDEX_INVALID ?
                cityList.get(mCityAdapter.getSelectedPosition()) : null;

        mBaseListener.onSelected(provinceBean, cityBean, districtBean);
        hidePop();

    }

    private EventHandler mHandler = new EventHandler(EventRunner.getMainEventRunner()){
        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
            if (event == null) {
                return;
            }

            switch (event.eventId) {
                case JDConst.INDEX_INVALID:
                    provinceList = (List<ProvinceBean>) event.object;
                    mProvinceAdapter.notifyDataChanged();
                    mCityListView.setItemProvider(mProvinceAdapter);

                    break;
                case JDConst.INDEX_TAB_PROVINCE:
                    provinceList = (List<ProvinceBean>) event.object;
                    mProvinceAdapter.notifyDataChanged();
                    mCityListView.setItemProvider(mProvinceAdapter);
                    break;
                case JDConst.INDEX_TAB_CITY:
                    cityList = (List<CityBean>) event.object;
                    mCityAdapter.notifyDataChanged();
                    if (cityList != null && !cityList.isEmpty()) {
                        mCityListView.setItemProvider(mCityAdapter);
                        tabIndex = JDConst.INDEX_TAB_CITY;
                    }
                    break;
                case JDConst.INDEX_TAB_AREA:
                    areaList = (List<DistrictBean>) event.object;
                    mAreaAdapter.notifyDataChanged();
                    if (areaList != null && !areaList.isEmpty()) {
                        mCityListView.setItemProvider(mAreaAdapter);
                        tabIndex = JDConst.INDEX_TAB_AREA;
                    }
                    break;
                default:
            }

            updateTabsStyle(tabIndex);
            updateIndicator();
        }
    };

    /**
     * 设置选中的城市tab是否可见
     */
    private void updateTabsStyle(int tabIndex) {
        switch (tabIndex) {
            case JDConst.INDEX_INVALID:
                mProTv.setTextColor(new Color(Color.getIntColor(colorAlert)));
                mProTv.setVisibility(Component.VISIBLE);
                mCityTv.setVisibility(Component.HIDE);
                mAreaTv.setVisibility(Component.HIDE);
                break;
            case JDConst.INDEX_TAB_PROVINCE:
                mProTv.setTextColor(new Color(Color.getIntColor(colorAlert)));
                mProTv.setVisibility(Component.VISIBLE);
                mCityTv.setVisibility(Component.HIDE);
                mAreaTv.setVisibility(Component.HIDE);
                break;
            case JDConst.INDEX_TAB_CITY:
                mProTv.setTextColor(new Color(Color.getIntColor(colorSelected)));
                mCityTv.setTextColor(new Color(Color.getIntColor(colorAlert)));
                mProTv.setVisibility(Component.VISIBLE);
                mCityTv.setVisibility(Component.VISIBLE);
                mAreaTv.setVisibility(Component.HIDE);
                break;
            case JDConst.INDEX_TAB_AREA:
                mProTv.setTextColor(new Color(Color.getIntColor(colorSelected)));
                mCityTv.setTextColor(new Color(Color.getIntColor(colorSelected)));
                mAreaTv.setTextColor(new Color(Color.getIntColor(colorAlert)));
                mProTv.setVisibility(Component.VISIBLE);
                mCityTv.setVisibility(Component.VISIBLE);
                mAreaTv.setVisibility(Component.VISIBLE);
                break;
            default:
        }

    }


}
